/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.googlecode.greenbridge.binder.excel;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;


/**
 * This class should really be brought into the Greenbridge core.
 * @author u368337
 */
public class GenerateParametersFromExcelSupport {


    /**
     * Generate a Collection, that is used in a JUnit paramaterized test from an
     * Excel spreadsheet.
     *
     * In the excel file each column header with #BeanName.prop will be bound to a
     * bean with class BeanName and property 'prop'.
     *
     * The test class is the current JUnit class under test. This is passed in so the
     * RangeChecker can look rows to run/skip for that class
     *
     * The result is a List of Arrays. Each entry in the list will be an array like the following:
     * [BeanToBind1, BeanToBind2, BeanToBind3, Map<String,String> namedCells, Integer rowNumber]
     * The first entries in the array are instances of the beansToBind. The namedCells is a name to value
     * map of the excel cells that start with _name. Row number is the current row.
     *
     *
     * @param excelFile The excel file to load from
     * @param sheet the index of the excel sheet. Zero based.
     * @param beansToBind The list of beans to bind to the excel sheet.
     * @param testClass The test class.
     * @return A list of Arrays.
     * @throws IOException
     * @throws BiffException
     */
    public static Collection generateCollection(File excelFile, int sheet, List<Class> beansToBind, Class testClass) throws IOException, BiffException {
        List params = new ArrayList();
        Workbook wb = Workbook.getWorkbook(excelFile);
        Sheet sheetDetails = wb.getSheet(sheet);
        Binder b = new Binder();
        NamedColumnToMapGenerator mapGenerator = new NamedColumnToMapGenerator(sheetDetails);

        Integer rowNumber = 1;
        for(BindingIterator iterator = b.interate(sheetDetails); iterator.hasNext();) {
            BindingRow row = iterator.next();
            // Only add the row if the range checker allows it.
            // by default, all are allowed, but when fixing tests it is nice to
            // selectively run one row.
            if(RangeChecker.isInRange(testClass, rowNumber)) {
                try {
                    List bound_results = new ArrayList();
                    for (Class clazz : beansToBind) {
                        Object bound = row.bind(clazz);
                        bound_results.add(bound);
                    }
                    Map<String, String> namedCells = mapGenerator.generateNameToCellMap(row.getCells());
                    bound_results.add(namedCells);
                    bound_results.add(rowNumber);

                    // add them to the list
                    params.add(bound_results.toArray());
                } catch (Exception e) {
                    System.out.println("Row " + rowNumber + " was skipped due to an error in binding");
                }
            }
            rowNumber++;
        }
        wb.close();
        return params;
        
    }

}
